﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace Crosshatch
{
    /// <summary>
    /// Base class for different types of dots
    /// </summary>
    abstract class Dot
    {
        public Vector2 position;

        /// <summary>
        /// The current speed of the dots
        /// </summary>
        public static float velocity { get { return 100 + DotManager.currentDifficulty * 10; } }

        /// <summary>
        /// Is this dot rotated 90 degrees?
        /// </summary>
        public bool isVertical;

        /// <summary>
        /// Is this dot rotated 180 degrees?
        /// </summary>
        public bool isFlipped;

        /// <summary>
        /// Does this dot do damage if hit?
        /// </summary>
        public bool damage;

        /// <summary>
        /// Time until the next frame
        /// </summary>
        private TimeSpan nextFrame;

        /// <summary>
        /// The dot type of this dot.
        /// </summary>
        public DotType thisType;

        /// <summary>
        /// Length of an animation frame
        /// </summary>
        private static TimeSpan frameLength = new TimeSpan(0, 0, 0, 0, 300);

        /// <summary>
        /// Current animation frame
        /// </summary>
        private int currentFrame;

        public int Width { get { return DotManager.GetGraphic(DotType.NORMAL).Width / 2; } }

        public int Height { get { return DotManager.GetGraphic(DotType.NORMAL).Height; } }


        public Dot(Vector2 position)
        {
            this.position = position;

            if (position.X < 0 || position.Y < 0)
                isFlipped = false;
            else
                isFlipped = true;

            if (position.X < 0 || position.X > Global.ScreenWidth)
                isVertical = false;
            else
                isVertical = true;
        }

        /// <summary>
        /// Size to increase collision box by
        /// </summary>
        private int collisionPad = 10;

        /// <summary>
        /// Return the collision rectangle for this dot
        /// </summary>
        /// <returns></returns>
        public Rectangle GetRectangle()
        {
            return new Rectangle(
                (int)position.X - Width / 2 - collisionPad / 2,
                (int)position.Y - Height / 2 - collisionPad / 2,
                Width + collisionPad,
                Height + collisionPad);
        }

        /// <summary>
        /// Update the dot's position
        /// </summary>
        /// <param name="gameTime"></param>
        public virtual void Move(GameTimerEventArgs gameTime)
        {
            //Update frame
            nextFrame -= gameTime.ElapsedTime;
            if (nextFrame <= TimeSpan.Zero)
            {
                nextFrame = frameLength;
                currentFrame = 1 - currentFrame;
            }
        }

        /// <summary>
        /// This dot was hit
        /// </summary>
        public virtual void Destroy() { }

        /// <summary>
        /// Draw thus dot to the given spriteBatch
        /// </summary>
        public void Draw(SpriteBatch batch)
        {
            batch.Draw(
                DotManager.GetGraphic(thisType),
                position,
                new Rectangle(
                    Width * currentFrame,
                    0,
                    Width,
                    Height),
                Color.White,
                0.0f,
                new Vector2(
                    Width / 2,
                    Height / 2),
                1.0f,
                SpriteEffects.None,
                1.0f);
        }
    }


    /// <summary>
    /// Represents a dot that simply travels across the screen
    /// </summary>
    class NormalDot : Dot
    {
        public NormalDot(Vector2 position)
            : base(position)
        {
            damage = false;
            thisType = DotType.NORMAL;
        }

        /// <summary>
        /// Update this dot
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Move(GameTimerEventArgs gameTime)
        {
            base.Move(gameTime);

            if (isVertical)
            {
                if (isFlipped)
                    position.Y -= velocity * (float)gameTime.ElapsedTime.TotalSeconds;
                else
                    position.Y += velocity * (float)gameTime.ElapsedTime.TotalSeconds;
            }
            else
            {
                if (isFlipped)
                    position.X -= velocity * (float)gameTime.ElapsedTime.TotalSeconds;
                else
                    position.X += velocity * (float)gameTime.ElapsedTime.TotalSeconds;
            }
        }
    }


    class DamageDot : Dot
    {
        public DamageDot(Vector2 position)
            : base(position)
        {
            damage = true;
            thisType = DotType.DAMAGE;
        }


        /// <summary>
        /// Update this dot
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Move(GameTimerEventArgs gameTime)
        {
            base.Move(gameTime);

            if (isVertical)
            {
                if (isFlipped)
                    position.Y -= velocity * (float)gameTime.ElapsedTime.TotalSeconds;
                else
                    position.Y += velocity * (float)gameTime.ElapsedTime.TotalSeconds;
            }
            else
            {
                if (isFlipped)
                    position.X -= velocity * (float)gameTime.ElapsedTime.TotalSeconds;
                else
                    position.X += velocity * (float)gameTime.ElapsedTime.TotalSeconds;
            }
        }
    }
}
